package com.rw.tool.util.string;

import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 字符串查找工具
 */
public class StringSearcher implements Iterator<Integer> {
    private final String input;

    private final String target;

    private int lastStartIndex = 0;

    private int startIndex = 0;

    /**
     * 从字符串中找到目标的子串
     *
     * @param input  字符串
     * @param target 目标子串
     */
    public StringSearcher(String input, String target) {
        this.input = input;
        this.target = target;
    }

    @Override
    public boolean hasNext() {
        return input.indexOf(target, startIndex) >= 0;
    }

    @Override
    public Integer next() {
        // 获取目标子串的位置
        int index = input.indexOf(target, startIndex);

        // 记录上一次的起始位置和下一次的起始位置
        lastStartIndex = startIndex;
        startIndex = index + target.length();
        return index;
    }

    /**
     * 获取上一次的查询起始位置
     */
    public int getLastStartIndex() {
        return lastStartIndex;
    }

    /**
     * 获取这一次的查询起始位置
     */
    public int getStartIndex() {
        return startIndex;
    }

    /**
     * 从字符串中替换所有目标子串
     *
     * @param input   输入字符串
     * @param target  目标子串
     * @param replace 替换的逻辑
     * @return 替换后的字符串
     */
    public static String replaceAll(String input, String target, Replace replace) {
        StringSearcher searcher = new StringSearcher(input, target);

        // 遍历，替换
        StringBuilder result = new StringBuilder();
        int count = 0;
        while (searcher.hasNext()) {
            int position = searcher.next();
            int startPosition = searcher.getLastStartIndex();
            result.append(input, startPosition, position);
            result.append(replace.replace(count));
            count++;
        }
        result.append(input, searcher.getStartIndex(), input.length());

        return result.toString();
    }

    /**
     * 从字符串中替换所有目标子串
     *
     * @param input   输入字符串
     * @param regex   目标子串的正则表达式
     * @param replace 替换的逻辑
     * @return 替换后的字符串
     */
    public static String replaceAll(String input, String regex, ReplaceByRegex replace) {
        // 构造正则表达式
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(input);

        // 遍历，替换
        StringBuffer result = new StringBuffer();
        int count = 0;
        while (matcher.find()) {
            String replaceTo = replace.replace(count, matcher.group());
            matcher.appendReplacement(result, replaceTo);
        }
        matcher.appendTail(result);

        return result.toString();
    }

    @FunctionalInterface
    public interface Replace {
        String replace(int count);
    }

    @FunctionalInterface
    public interface ReplaceByRegex {
        String replace(int count, String replaced);
    }
}
